home *** CD-ROM | disk | FTP | other *** search
- page 96,132
- ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
- ;§ §
- ;§ ディレクトリエントリ ソート ユーティリティ §
- ;§ §
- ;§ DSORT.EXE Ver1.30 §
- ;§ §
- ;§ Copyright (C) by 福地 邦雄 1991-1992. All rights reserved. §
- ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
- .MODEL SMALL,C
- .data
- ;
- public errorno ;プログラム終了時のステータスに指定する
- errorno dw ? ;エラーコード
- ;
- allocmsg db 'メモリが獲得できません',0dh,0ah ;メモリ獲得エラーの
- alcmsgsiz equ $-allocmsg ;メッセージ
- ;
- .code
- ;
- ;------------------------------------------------------------------------------
- ;
- ; getargs
- ; コマンドライン入力を分解してポインタのリストにする
- ; 空白,タブを区切り文字とする プログラム名はサポートされない
- ;
- ; TYPE near call
- ; IN ds=psp
- ; 200h以上のスタックサイズ
- ; OUT ss:bp にファーポインタリストの先頭アドレス
- ; ax に文字列の個数 ゼロフラグに個数のテスト結果
- ; ディレクションフラグ ダウン方向
- ;
- ; 保存レジスタ ds のみ
- ;
- ;------------------------------------------------------------------------------
- ;
- stackwrk equ 01c0h
- argcwrk equ word ptr [bp]
- returnaddr equ word ptr [bp+2]
- strings equ word ptr [bp+4]
- cmdlen equ ds:[80h]
- cmdtop equ 81h
- SPC equ 20h
- TAB equ 09h
- ;
- public getargs
- getargs proc near
- ;
- sub sp,stackwrk ;文字列とポインタリスト領域の確保
- mov bp,sp
- mov ax,[bp+stackwrk] ;リターンアドレスのセーブ
- mov returnaddr,ax
- xor ax,ax ;ワーク領域&レジスタの初期化
- mov argcwrk,ax
- mov cx,ax
- lea di,strings
- mov cl,cmdlen ;コマンドライン文字列長の取得
- mov si,cx
- inc cx
- mov bx,cmdtop
- mov byte ptr [si+bx],SPC ;コマンドライン終端の改行コードを空白に
- ;
- spaceloop: ;空白,タブをスキップする
- cmp byte ptr [bx],SPC
- je nextchar
- cmp byte ptr [bx],TAB
- jne spaceout
- nextchar:
- inc bx
- loop spaceloop
- jmp argend
- ;
- spaceout: ;
- mov ss:[di],bx ;文字列の先頭オフセットのセーブ
- mov word ptr ss:[di+2],0 ;文字列長さ初期化
- lea di,[di+4]
- inc argcwrk ;文字列個数のカウントアップ
- nospcloop:
- inc word ptr ss:[di-2] ;文字列長さのカウントアップ
- dec cx
- jcxz stringend
- inc bx
- cmp byte ptr [bx],SPC ;空白,タブが現れるまでループ
- je stringend
- cmp byte ptr [bx],TAB
- je stringend
- jmp short nospcloop
- stringend:
- mov byte ptr [bx],0 ;文字列終端に 0 をセット
- inc bx
- loop spaceloop ;空白,タブのスキップ
- ;
- argend:
- mov ax,argcwrk ;文字列個数をチェック 0 なら終了
- test ax,ax
- jnz argsset
- add sp,stackwrk
- xor ax,ax
- ret
- ;
- argsset:
- mov dx,di ;文字列情報の最終アドレスをセーブ
- mov bx,di ;
- std ;コピー方向=ダウンカウント
- lea di,[bp+stackwrk+1] ;スタック最終アドレスを取得
- @do until ;文字列をスタックへコピー
- lea bx,[bx-4]
- mov cx,ss:[bx+2] ;文字列長取得
- mov ss:[bx+2],ss ;コピー後セグメントセット
- mov si,ss:[bx] ;文字列終端アドレス取得
- add si,cx
- inc cx ;終端文字分をカウントアップ
- mov es,ss:[bx+2]
- rep movsb
- mov ss:[bx],di ;スタック上の文字列オフセット設定
- inc word ptr ss:[bx]
- dec ax
- @doend (zf,on)
- ; ;ファーポインタリストのコピー
- and di,0fffeh ;コピー先設定
- lea di,[di-2]
- mov cx,dx
- mov si,cx ;コピー元設定
- lea si,[si-2]
- sub cx,bx
- shr cx,1 ;コピーカウント(ワード)設定
- push ds
- mov ds,ss:[si] ;スタックセグメント取得
- rep movsw
- pop ds
- ;
- mov ax,argcwrk
- mov bx,returnaddr ;リターンアドレス設定
- mov ss:[di],bx
- lea bp,[di+2] ;ファーポインタリストのオフセット
- mov sp,di
- test ax,ax
- ret
- ;
- getargs endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; asctoint
- ; アスキー10進数字列から、16ビットバイナリーへの変換
- ; 数字でない文字に出会った時点で終了する
- ;
- ; TYPE near call
- ; IN es:di アスキー10進数字列アドレス
- ; OUT ax 変換した数値
- ; es:di 変換時の数字でない文字のアドレス
- ; 保存レジスタ bx,cx,dx,si,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- public asctoint
- asctoint proc uses bx cx dx
- ;
- xor ax,ax ;変換中の数値&変換後通知データ
- mov cx,ax ;獲得する(した)文字
- mov bx,10 ;10進変換のための乗数
- @do repeat
- mov cl,es:[di] ;文字獲得
- @if (cl,<,'0'),or,(cl,>,'9')
- @doexit
- @ifend
- and cl,0fh ;文字を数値に変換
- mul bx ;今までの変換データを10倍
- add ax,cx ;獲得した数値を加算
- inc di ;次の文字位置へ
- @doend
- test ax,ax ;ゼロフラグ設定
- ret
- ;
- asctoint endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; inttoasc0
- ; 16ビットバイナリをアスキー10進数字列に変換する
- ; 5 桁固定で 頭の 0 も出力する
- ;
- ; TYPE near call
- ; IN ax 16ビットバイナリ
- ; es:di 変換後のアスキー10進数字列を格納するアドレス
- ; OUT es:di 変換したアスキー10進数字列の次のアドレス
- ; 保存レジスタ bx,cx,dx,si,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- public inttoasc0
- inttoasc0 proc uses cx dx
- ;
- cld ;変換後文字列出力方向 アップ方向
- mov cx,100 ;10進変換のための除数
- xor dx,dx ;32/16ビット除算用の上位16ビットクリア
- div cx ;100で割る DX=余り AX=商
- div cl ;商を更に100で割る AH=余り AL=商
- add al,'0' ;万の位を数字文字に変換して出力
- stosb
- mov al,ah ;千,百の位を数字文字に変換して出力
- aam
- add ax,'00'
- xchg ah,al
- stosw
- mov al,dl ;十,一の位を数字文字に変換して出力
- aam
- add ax,'00'
- xchg ah,al
- stosw
- ret
- ;
- inttoasc0 endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; dosstdout
- ; MS-DOSのハンドル2番 標準出力へデータを出力する
- ; エラーが起こった時はアボートする
- ;
- ; TYPE near call
- ; IN cx 出力データ長
- ; ds:dx 出力データの先頭アドレス
- ; OUT なし
- ; 保存レジスタ si,di,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- public dosstdout
- dosstdout proc
- ;
- mov ah,40h
- mov bx,1
- int 21h
- @if (cf,on)
- mov ah,4ch
- int 21h
- @ifend
- ret
- ;
- dosstdout endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; dosallocx
- ; MS-DOSのメモリ獲得を呼び出す、獲得出来ない時は標準出力へエラー
- ; メッセージを出力してアボートする
- ;
- ; TYPE near call
- ; IN dx:ax 獲得したいメモリのバイトサイズ
- ; OUT ax 割り当てられたメモリのセグメントアドレス
- ; 保存レジスタ cx,si,di,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- public dosallocx
- dosallocx proc uses bx cx
- ;
- mov cl,4
- add ax,15
- adc dx,0
- shr ax,cl
- and dx,0fh
- ror dx,cl
- mov bx,ax
- or bx,dx
- mov ah,48h
- int 21h
- @if (cf,on)
- mov errorno,ax
- mov dx,offset allocmsg
- mov cx,alcmsgsiz
- jmp abort
- @ifend
- ret
- ;
- dosallocx endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; abort
- ; 標準出力へメッセージを出力した後、プログラム終了する
- ; 終了時に終了コードを設定する
- ;
- ; TYPE near call
- ; IN cx 出力データ長
- ; ds(data):dx 出力データの先頭アドレス
- ; ds(data):errorno 終了コード
- ; OUT なし
- ; 保存レジスタ si,di,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- public abort
- abort proc
- ;
- mov ax,seg _data
- mov ds,ax
- mov ah,40h
- mov bx,1
- int 21h
- ;
- mov ax,errorno
- mov ah,4ch
- int 21h
- ;
- abort endp
- ;
- end